<template>
  <div
    v-show="visible"
    :style="{width: formatter(width), left: formatter(left), top: formatter(top), cursor: legendData.positionType === '5' ? 'move' : 'default'}"
    :class="['bg-white legend-container p-h-mini d-flex ai-c', `col-${columnsLength}`]"
    @mousedown="handleMouseDown"
    ref="self"
  >
    <div
      class="d-flex legend-item d-flex ai-c"
      v-for="(item, i) in finalList"
      :key="i"
    >
      <div
        class="d-flex ai-c jc-c"
        style="width: 44px;"
      >
        <img
          class="icon"
          :src="item.icon"
          v-if="item.type.includes('icon')"
        >
        <div
          class="rect"
          :style="{background: item.color}"
          v-if="item.type.includes('rect')"
        />
        <div
          class="line"
          :style="{background: item.color}"
          v-if="item.type.includes('line')"
        />
      </div>
      <span class="f-14">{{ item.text }}</span>
    </div>
  </div>
</template>

<script>
import { getLegendStyle } from '../utils'
import { debounce } from 'throttle-debounce'
import { mapState } from 'vuex'
export default {
  name: 'LegendContainer',
  props: {
    value: {
      type: Boolean,
      default: false
    },
    containerHeight: {
      type: Number,
      default: 0
    },
    containerWidth: {
      type: Number,
      default: 0
    },
    list: {
      type: Array,
      default: () => ([])
    }
  },
  data () {
    return {
      visible: this.value,
      minWidth: 80,
      left: 0,
      top: 0,
      finalList: []
    }
  },
  created () {
    this.init()
    this.debounceCommit = debounce(800, this.updateLegendData)
    this.$root.$on('updateMapMaking', this.updateMapMaking)
    this.$root.$on('updateLegend', this.updateLegend)
  },
  beforeDestroy () {
    this.$root.$off('updateMapMaking', this.updateMapMaking)
    this.$root.$off('updateLegend', this.updateLegend)
  },
  watch: {
    value (v) {
      this.visible = v
    },
    visible (v) {
      this.$emit('input', v)
      if (this.visible) {
        this.updateLegend()
      }
    },
    list () {
      this.init()
    },
    containerWidth (v, old) {
      this.oldWidth = old
      this.updateLegend()
    },
    containerHeight (v, old) {
      this.oldHeight = old
      this.updateLegend()
    }
  },
  computed: {
    ...mapState('map-making', ['legendData']),
    columnsLength () {
      if (this.finalList.length <= 6) {
        return 1
      } else if (this.finalList.length > 6 && this.finalList.length <= 12) {
        return 2
      } else {
        return 3
      }
    },
    width () {
      if (this.finalList.length <= 6) {
        return 150
      } else if (this.finalList.length > 6 && this.finalList.length <= 12) {
        return 300
      } else {
        return 450
      }
    }
  },
  methods: {
    updateMapMaking () {
      if (!isNaN(Number(this.legendData.left)) && !isNaN(Number(this.legendData.top))) {
        this.left = Number(this.legendData.left) * this.containerWidth
        this.top = Number(this.legendData.top) * this.containerHeight
      }
    },
    init () {
      this.finalList = Array.from(new Set(this.list.map(item => item.text))).map(name => {
        const item = this.list.find(l => l.text === name)
        const l = getLegendStyle(item.layerId)
        return {
          ...item,
          type: l.type,
          icon: l.icon,
          color: l.color
        }
      })
      this.updateLegend()
    },
    handleMouseDown (e) {
      if (this.legendData.positionType !== '5') return
      this.mouseX = e.x
      this.mouseY = e.y
      this.currentLeft = this.left
      this.currentTop = this.top
      this.dragging = true
      document.body.addEventListener('mousemove', this.handleMouseMove)
      document.body.addEventListener('mouseup', this.handleMouseUp)
    },
    handleMouseMove (e) {
      if (!this.dragging) return
      this.$refs.self.style.cursor = 'move'
      const left = this.currentLeft + (e.x - this.mouseX)
      const top = this.currentTop + (e.y - this.mouseY)
      this.left = Math.min(Math.max(0, left), this.containerWidth - this.$refs.self.offsetWidth)
      this.top = Math.min(Math.max(0, top), this.containerHeight - this.$refs.self.offsetHeight)
      this.debounceCommit()
    },
    handleMouseUp () {
      this.dragging = false
      document.body.removeEventListener('mousemove', this.handleMouseMove)
      document.body.removeEventListener('mouseup', this.handleMouseUp)
    },
    formatter (num) {
      return num + 'px'
    },
    updateLegendData () {
      this.$store.commit('map-making/setLegendData', Object.assign(this.legendData, { left: this.left / this.containerWidth, top: this.top / this.containerHeight }))
    },
    updatePosition () {
      if (this.oldWidth && this.oldHeight) {
        const leftRatio = this.left / this.oldWidth
        const topRatio = this.top / this.oldHeight
        this.left = Math.min(Math.max(0, leftRatio * this.containerWidth), this.containerWidth - this.$refs.self.offsetWidth)
        this.top = Math.min(Math.max(0, topRatio * this.containerHeight), this.containerHeight - this.$refs.self.offsetHeight)
        this.oldWidth = null
        this.oldHeight = null
        this.debounceCommit()
      }
    },
    async updateLegend () {
      await this.$nextTick()
      if (this.legendData.positionType === '5') {
        this.updatePosition()
      } else {
        if (this.legendData.positionType === '1') {
          this.left = 0
          this.top = 0
        } else if (this.legendData.positionType === '2') {
          this.left = 0
          this.top = this.containerHeight - this.$refs.self.offsetHeight
        } else if (this.legendData.positionType === '3') {
          this.left = this.containerWidth - this.$refs.self.offsetWidth
          this.top = 0
        } else if (this.legendData.positionType === '4') {
          this.left = this.containerWidth - this.$refs.self.offsetWidth
          this.top = this.containerHeight - this.$refs.self.offsetHeight
        }
        this.debounceCommit()
        this.oldWidth = null
        this.oldHeight = null
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.legend-container {
  position: absolute;
  user-select: none;
  border: 1px solid #000;
  z-index: 5;
  flex-wrap: wrap;
  padding-top: 10px;

  .legend-item {
    margin-bottom: 10px;

    .icon {
      width: 16px;
      height: 16px;
      margin-right: 6px;
    }

    .rect {
      width: 16px;
      height: 10px;
      margin-right: 6px;
    }

    .line {
      width: 16px;
      height: 8px;
      margin-right: 6px;
    }
  }
}

.legend-container.col-1 {
  .legend-item {
    width: 100%;
  }
}

.legend-container.col-2 {
  gap: 10px;

  .legend-item {
    width: calc(50% - 15px);
  }
}

.legend-container.col-3 {
  gap: 10px;

  .legend-item {
    width: calc(33.33% - 13.33px);
  }
}
</style>
